import os
import time

import requests
from jsonlines import jsonlines
from selenium.webdriver.common.by import By
from seleniumwire import webdriver

import assistant

logger = assistant.logger
SAVE_PATH = './output/data.jsonl'
os.makedirs(os.path.dirname(SAVE_PATH), exist_ok=True)
header = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    "Cache-Control": "max-age=0",
    "Connection": "keep-alive",
    # "Cookie": 'll="118371"; bid=Fsbe9sfmWeE; douban-fav-remind=1; _pk_id.100001.4cf6=418738468fffe252.1687100016.; __yadk_uid=QALpMKXECMQyz7KgtiAoZB3f9sDCr7wk; _vwo_uuid_v2=D22F58820969D590BFCDCC8325B7D22D5|2ef8c52d900cdee29e6c7a70634e2fd9; viewed="35121203_36142067_36206397"; _ga=GA1.1.1410860224.1696751048; _ga_Y4GN1R87RG=GS1.1.1696751048.1.1.1696751067.0.0.0; ap_v=0,6.0; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1696767285%2C%22https%3A%2F%2Fm.douban.com%2F%22%5D; _pk_ses.100001.4cf6=1; ct=y; dbcl2="231323398:RLeLw+DqlGM"; ck=pxhW; push_noty_num=0; push_doumail_num=0',
    "Host": "movie.douban.com",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    # "sec-ch-ua":"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "Windows",
}


def get_comment_and_title_by_movie_id(movie_id: str | int, num: int = 600):
    """
    通过电影id获取该电影的短评和标题.
    可以访问到600条, 豆瓣网站的最大展示量就只有六百条
    limit调整20会有特殊对待, 因为前端网页就是用的20 ,当为20时他会区分是否已登录, 未登录只给220条数据
    """
    assert num <= 600, "num must less than 600"
    limit = 100
    times = num // limit
    logger.info(f'开始爬取电影的comment和title, movie_id:{movie_id}')
    for start in range(times):
        start = start * limit
        logger.info(f'开始爬取:{start}--{start + limit}')
        url = f"https://movie.douban.com/subject/{movie_id}/comments?start={start}&limit=100&status=P&sort=new_score"
        logger.info(f'url: {url}')
        res = assistant.send_request(url, header)
        if res.status_code != 200:
            print(res.status_code)
            return
        xpath_comment = '//*[@id="comments"]/div/div[2]/p/span/text()'
        comments = assistant.handle_xpath(res.text, xpath_comment)
        logger.info(f'comments:{comments}')
        xpath_title = '//*[@id="comments"]/div/div[2]/h3/span[2]/span[2]/@title'
        titles = assistant.handle_xpath(res.text, xpath_title)
        logger.info(f'处理专辑成功,title: {titles}')
        if len(comments) != len(titles):
            logger.error('评论数和标题数不一致, 跳过该页')
            continue
        for comment, title in zip(comments, titles):
            res = {
                "title": title,
                "comment": comment
            }
            with jsonlines.open(SAVE_PATH, mode='a') as f:
                f.write(res)


def get_movies_id(num: int = 200):
    """
    得到各个电影的id
    """
    url = "https://movie.douban.com/explore"
    driver = webdriver.Chrome()
    driver.get(url)
    driver.implicitly_wait(0.5)
    time.sleep(0.5)
    button = driver.find_element(by=By.CSS_SELECTOR,
                                 value="#app > div > div.explore-sticky > div > div.playable-filter > div")
    button.click()
    driver.implicitly_wait(0.5)
    time.sleep(0.5)
    html = driver.page_source
    xpath_a = '//*[@id="app"]/div/div[2]/ul/li/a/@href'
    xpath_next = '//*[@id="app"]/div/div[2]/div/button'
    res = set()
    href_list = assistant.handle_xpath(html, xpath_a)
    res.update(href_list)
    logger.info(f'处理成功,len(res): {len(res)}')
    logger.info(f'{res}')
    while len(res) < num:
        html_text, driver = assistant.do_a_click_to_a_driver(driver, xpath_next)
        a_list = assistant.handle_xpath(html_text, xpath_a)
        res.update(a_list)
        logger.info(f'处理成功,len(res): {len(res)}')
        logger.info(f'{res}')
    return [x.strip().split('/')[-1] for x in res]


if __name__ == '__main__':
    if os.path.exists('./output/data.jsonl'):
        os.remove('./output/data.jsonl')
    movies_id = get_movies_id(num=200)
    assistant.write_movie_ids_to_file(movies_id, './output/movie_ids.txt')
    movies_id = assistant.read_movie_ids_from_file('./output/movie_ids.txt')
    for id in movies_id:
        get_comment_and_title_by_movie_id(id, num=600)
